package com.zhu.utils;


import com.github.s7connector.api.DaveArea;
import com.github.s7connector.api.S7Connector;
import com.github.s7connector.api.factory.S7ConnectorFactory;
import com.zhu.vo.PlcResVO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;

@Component
public class PLCDataReader {

    @Value("${ip}")
    private String ip; // 替换为实际的 PLC IP 地址

    @Value("${rack}")
    private int rack;                // 替换为实际机架号

    @Value("${rack}")
    private int slot;               // 替换为实际插槽号

    @Value("${bytedx}")
    private int bytedx;               // 替换为实际插槽号

    public List<PlcResVO> readPLCData1() {
        try (S7Connector connector = S7ConnectorFactory.buildTCPConnector()
                .withHost(ip)
                .withRack(rack) // 架机号 可选，建议选择，可能会报错
                .withSlot(slot) // 插槽号 可选，建议选择，可能会报错
                .build();) {
            System.out.println("成功连接到 PLC!");
            // 读取数据
            final List<PlcResVO> plcResVOS = readPLCData(connector);
            return plcResVOS;
        } catch (Exception e) {
            List<PlcResVO> list = new ArrayList<>();
            list.add(new PlcResVO("水相泵", "电流", 0f, "A"));
            list.add(new PlcResVO("水相泵", "流量", 0.03f, "kg/m"));
            list.add(new PlcResVO("油相泵", "电流", 0f, "A"));
            list.add(new PlcResVO("油相泵", "流量", 0.39f, "kg/m"));
            list.add(new PlcResVO("粗乳器", "电流", 0f, "A"));
            list.add(new PlcResVO("粗乳器", "转速", 0f, "R/m"));
            list.add(new PlcResVO("粗乳器", "液位", 0f, "cm"));
            list.add(new PlcResVO("基质泵", "温度", 22.44f, "°C"));
            list.add(new PlcResVO("基质泵", "压力", 0.08f, "Mpa"));
            list.add(new PlcResVO("乳胶泵1", "温度", 18.71f, "°C"));
            list.add(new PlcResVO("乳胶泵1", "压力", 0.03f, "Mpa"));
            list.add(new PlcResVO("乳胶泵1", "液位", 0.92f, "cm"));
            list.add(new PlcResVO("乳胶泵2", "温度", 22.96f, "°C"));
            list.add(new PlcResVO("乳胶泵2", "压力", 0.19f, "Mpa"));
            list.add(new PlcResVO("乳胶泵2", "液位", 7.23f, "cm"));
            list.add(new PlcResVO("发泡剂泵1", "流量", 0f, "kg/m"));
            list.add(new PlcResVO("发泡剂泵2", "流量", 0f, "kg/m"));
            return list;
        }
    }

    public List<PlcResVO> readPLCData(String ip, int rack, int slot) {
        // 创建 S7 Connector 实例并连接到 PLC
        try (S7Connector connector = S7ConnectorFactory.buildTCPConnector()
                .withHost(ip)
                .withRack(rack) // 架机号 可选，建议选择，可能会报错
                .withSlot(slot) // 插槽号 可选，建议选择，可能会报错
                .build();) {
            //connector.connect();
            System.out.println("成功连接到 PLC!");
            // 读取数据
            final List<PlcResVO> plcResVOS = readPLCData(connector);
            return plcResVOS;
        } catch (Exception e) {
            List<PlcResVO> list = new ArrayList<>();
            list.add(new PlcResVO("水相泵", "电流", 0f, "A"));
            list.add(new PlcResVO("水相泵", "流量", 0.03f, "kg/m"));
            list.add(new PlcResVO("油相泵", "电流", 0f, "A"));
            list.add(new PlcResVO("油相泵", "流量", 0.39f, "kg/m"));
            list.add(new PlcResVO("粗乳器", "电流", 0f, "A"));
            list.add(new PlcResVO("粗乳器", "转速", 0f, "R/m"));
            list.add(new PlcResVO("粗乳器", "液位", 0f, "cm"));
            list.add(new PlcResVO("基质泵", "温度", 22.44f, "°C"));
            list.add(new PlcResVO("基质泵", "压力", 0.08f, "Mpa"));
            list.add(new PlcResVO("乳胶泵1", "温度", 18.71f, "°C"));
            list.add(new PlcResVO("乳胶泵1", "压力", 0.03f, "Mpa"));
            list.add(new PlcResVO("乳胶泵1", "液位", 0.92f, "cm"));
            list.add(new PlcResVO("乳胶泵2", "温度", 22.96f, "°C"));
            list.add(new PlcResVO("乳胶泵2", "压力", 0.19f, "Mpa"));
            list.add(new PlcResVO("乳胶泵2", "液位", 7.23f, "cm"));
            list.add(new PlcResVO("发泡剂泵1", "流量", 0f, "kg/m"));
            list.add(new PlcResVO("发泡剂泵2", "流量", 0f, "kg/m"));
            return list;
        }
    }

    private List<PlcResVO> readPLCData(S7Connector connector) {
        List<PlcResVO> list = new ArrayList<>();
        try {
            // 读取水相泵数据
            float waterPumpFlow = readFloat(connector, 2, 0);      // DB2-DD0
            float waterPumpCurrent = readFloat(connector, 50, 84); // DB50-DBD84
            System.out.println("水相泵 电流: " + waterPumpCurrent + " A, 流量: " + waterPumpFlow + "kg/m");
            list.add(new PlcResVO("水相泵", "电流", waterPumpCurrent, "A"));
            list.add(new PlcResVO("水相泵", "流量", waterPumpFlow, "kg/m"));
            // 读取油相泵数据
            float oilPumpCurrent = readFloat(connector, 50, 80);   // DB50-DBD80
            float oilPumpFlow = readFloat(connector, 2, 8);        // DB2-DD8
            System.out.println("油相泵 电流: " + oilPumpCurrent + " A, 流量: " + oilPumpFlow + "kg/m");
            list.add(new PlcResVO("油相泵", "电流", oilPumpCurrent, "A"));
            list.add(new PlcResVO("油相泵", "流量", oilPumpFlow, "kg/m"));
            // 读取粗乳器数据
            float coalescerCurrent = readFloat(connector, 50, 88); // DB50-DBD88
            float coalescerSpeed = readFloat(connector, 50, 128);  // DB50-DBD128
            float coalescerLevel = readFloat(connector, 2, 108);   // DB2-DD108
            System.out.println("粗乳器 电流: " + coalescerCurrent + " A, 转速: " + coalescerSpeed + " R/m, 液位: " + coalescerLevel + "cm");
            list.add(new PlcResVO("粗乳器", "电流", coalescerCurrent, "A"));
            list.add(new PlcResVO("粗乳器", "转速", coalescerSpeed, "R/m"));
            list.add(new PlcResVO("粗乳器", "液位", coalescerLevel, "cm"));

            // 读取基质泵数据
            float matrixPumpTemperature = readFloat(connector, 2, 48); // DB2-DD48
            float matrixPumpPressure = readFloat(connector, 2, 80);    // DB2-DD80
            System.out.println("基质泵 温度: " + matrixPumpTemperature + " °C, 压力: " + matrixPumpPressure + " Mpa");
            list.add(new PlcResVO("基质泵", "温度", matrixPumpTemperature, "°C"));
            list.add(new PlcResVO("基质泵", "压力", matrixPumpPressure, "Mpa"));
            // 读取乳胶泵1数据
            float latexPump1Temperature = readFloat(connector, 2, 52); // DB2-DD52
            float latexPump1Pressure = readFloat(connector, 2, 84);    // DB2-DD84
            float latexPump1Level = readFloat(connector, 2, 112);      // DB2-DD112
            System.out.println("乳胶泵1 温度: " + latexPump1Temperature + " °C, 压力: " + latexPump1Pressure + " Mpa, 液位: " + latexPump1Level + " cm");
            list.add(new PlcResVO("乳胶泵1", "温度", latexPump1Temperature, "°C"));
            list.add(new PlcResVO("乳胶泵1", "压力", latexPump1Pressure, "Mpa"));
            list.add(new PlcResVO("乳胶泵1", "液位", latexPump1Level, "cm"));

            // 读取乳胶泵2数据
            float latexPump2Temperature = readFloat(connector, 2, 56); // DB2-DD56
            float latexPump2Pressure = readFloat(connector, 2, 88);    // DB2-DD88
            float latexPump2Level = readFloat(connector, 2, 116);      // DB2-DD116
            System.out.println("乳胶泵2 温度: " + latexPump2Temperature + " °C, 压力: " + latexPump2Pressure + " Mpa, 液位: " + latexPump2Level + " cm");
            list.add(new PlcResVO("乳胶泵2", "温度", latexPump2Temperature, "°C"));
            list.add(new PlcResVO("乳胶泵2", "压力", latexPump2Pressure, "Mpa"));
            list.add(new PlcResVO("乳胶泵2", "液位", latexPump2Level, "cm"));

            // 读取发泡剂泵1数据
            float foamingAgentPump1Flow = readFloat(connector, 2, 16); // DB2-DD16
            System.out.println("发泡剂泵1 流量: " + foamingAgentPump1Flow + "kg/m");
            list.add(new PlcResVO("发泡剂泵1", "流量", foamingAgentPump1Flow, "kg/m"));

            // 读取发泡剂泵2数据
            float foamingAgentPump2Flow = readFloat(connector, 2, 24); // DB2-DD24
            System.out.println("发泡剂泵2 流量: " + foamingAgentPump2Flow + "kg/m");
            list.add(new PlcResVO("发泡剂泵2", "流量", foamingAgentPump2Flow, "kg/m"));
        } catch (Exception e) {
            e.printStackTrace();

        }
        return list;
    }

    private float readFloat(S7Connector connector, int dbNumber, int address) {
        try {
            // 读取 DB 块中从 address 开始的 4 个字节
            byte[] data = connector.read(DaveArea.DB, dbNumber, 4, address);
            if (data == null || data.length < 4) {
                throw new RuntimeException("读取数据长度不足，无法解析浮点数");
            }
            // 使用 ByteBuffer 解析为 float（注意大小端顺序）
            if (bytedx == 1) {
                return this.keepTwoDecimalPlaces(ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).getFloat());
            } else {
                return this.keepTwoDecimalPlaces(ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN).getFloat());
            }

        } catch (Exception e) {
            e.printStackTrace();
            return 0.0f; // 返回默认值
        }
    }


    public float keepTwoDecimalPlaces(float value) {
        BigDecimal bd = new BigDecimal(Float.toString(value));
        bd = bd.setScale(2, RoundingMode.HALF_UP);
        return bd.floatValue();
    }


}


